No bulk emails (User opt out): This is what happens when someone opts out using the link in a bulk mailing. This means they won't be included in any bulk mailing. It doesn't affect sending single messages to that contact.
Do not email: This means we can't/shouldn't email them at all, even singly. Actions > Send an Email won't be available.
Deceased: AFAIK works similar to "Do not email".
On hold: Set by the CiviMail bounce processing. Probably means a bulk mail to them bounced. This means the address is invalid/inaccessible, not necessarily that they don't want us contacting them.
Unsubscribe: This is a different meaning and a different link to "Opt out". This is not a flag that is visible from the contact summary, but from the groups tab. Bulk emails are sent to groups; unsubscribe causes the contact to be set as 'removed' from the group that caused them to get that email. It does not opt them out of all mail or even all bulk email.
(One of) their email address(es) should be marked as primary. This should happen automatically but if they don't have a primary email address this might cause issues.
Another possible reason for the difference in the count is if you have (allow) multiple contacts to have the same email address and you have duplicate elimination turned on for a mailing. This has happened a number of times with various installs that I have worked with.
I am not aware of any magic solution that provides you a way to easily determine which contacts are not included. I suspect, to identify who was excluded, you might be able to (after the mailing) use either Advanced Search or Search Builder to do a query that compares the group contacts with the Bulk Email activity for the mailing. (Ala, in the group but not the activity.)