I can't find any empty tags, but some tags with 0 uses.
Means, there are some tags left, that do not have any assignments to threads anymore as they were removed from threads.
Some others were created in ACP, but were never used. last_use_date is then 0.
If I extend the WHERE-clause by "AND last_use_date > 0" it works
SELECT COUNT(*) AS nbItems,tag.*
FROM xf_tag_content AS tag_content
LEFT JOIN xf_tag AS tag ON (tag.tag_id=tag_content.tag_id)
WHERE content_type='thread' AND last_use_date > 0
GROUP BY tag_id
ORDER BY nbItems DESC