How do I only display a list of categories that have entries and hide empty categories?
To display a list of categories that are in use (and make sure you are not displaying any categories that don't have content associated with them), you will need to take a couple of steps. Here's a barebones examples of the code we will need, and we will break it out into more detail below.
{% set entryIds = craft.entries.section('blog').ids() %}
{% set categories = craft.categories.relatedTo({ sourceElement: entryIds }).groupId(1).find() %}
{% for category in categories %}
<li><a href="{{ category.url }}">{{ category.title }}</a></li>
{% endfor %}
First, we want to grab all of the entry ids from the Section of content which we want to display categories for.
{% set entryIds = craft.entries.section('blog').ids() %}
Next, we will use the craft.categories tags relatedTo() method to only return categories that have a relationship with one of our entry ids.
{% set categories = craft.categories.relatedTo({ sourceElement: entryIds }).groupId(1).find() %}
Once we have our list of categories that are in use, we can loop through those categories and display them in our template:
<ul>
{% for category in categories %}
<li><a href="{{ category.url }}">{{ category.title }}</a></li>
{% endfor %}
</ul>