There's several reasons an auto_increment column can have "skipped" values... a failed insert, an INSERT IGNORE ..., an INSERT ... ON DUPLICATE KEY, a value specified in an insert that is higher than the next value, rows inserted and subsequently deleted, an ALTER TABLE ... AUTO_INCREMENT =
statement, there's all sorts of reasons.
What AUTO_INCREMENT guarantees you is a unique value; it doesn't guarantee that none will be skipped.
There is usually no need to modify id values, and it can cause some significant problems for users and applications, if they are (reasonably) expecting id values to be immutable. In terms of the database, be aware of foreign keys (either enforced by InnoDB, or implied and not enforced as with MyISAM), or triggers that may fire, etc.
To set new values for the ID column, so that there are no "skipped" values (assuming no foreign key constraints will be violated)
in this example, starting with id values following id 2001, such that next higher id value (2003 in your example) will be set to 2002, the next higher id value after that, will be set to 2003, and so on...
UPDATE mytable t
JOIN ( SELECT s.id
, @new_id := @new_id + 1 AS new_id
FROM ( SELECT @new_id := 2001 ) i
JOIN ( SELECT r.id
FROM mytable r
WHERE r.id > 2001
ORDER BY r.id
) s
ORDER BY s.id
) u
ON t.id = u.id
SET t.id = u.new_id
SQL Fiddle Here
Again, all the warnings that "skipped" values are not a problem, and resetting id values can cause big problems (as mentioned above) apply.
To reset the AUTO_INCREMENT value for the table, it's a simple ALTER TABLE statement. If you attempt to set it lower than the maximum id value, MySQL uses the maximum id value. So, you can just
ALTER TABLE mytable AUTO_INCREMENT = 1;
This statement does not change existing rows, it just sets the auto increment value to the lowest value, such that the next auto increment retrieved will be one higher than maximum id value currently in the table.
To answer you first question, it's harder to get a list of "skipped" id values, since there isn't a row source for them.
If we just want to check if any id values are "skipped", we can make use of the query in the inline view aliased as u (from the UPDATE statement above). We change that UPDATE into a SELECT, and just filter out rows where the id value matches the (generate) new_id value:
SELECT u.*
FROM ( SELECT s.id
, @new_id := @new_id + 1 AS new_id
FROM ( SELECT @new_id := 2001 ) i
JOIN ( SELECT r.id
FROM mytable r
WHERE r.id > 2001
ORDER BY r.id
) s
ORDER BY s.id
) u
WHERE u.id <> u.new_id
ORDER BY u.id
If that query returns no rows, then there are no "skipped" values.