How can I output a list of categories that are not empty? In other words, categories must have at least one enabled entry assigned to them.
To get all categories that are related to an entry you would do this:

{% set allEntries = craft.entries.limit(null) %}
{% set categoriesInUse = craft.categories.relatedTo(allEntries) %}


If you want to narrow down to a specific category group or any other category property you can do it like so:

{% set newsCategories = craft.categories.group('newsCategories').limit(null) %}
{% set entriesWithNewsCategories = craft.entries.relatedTo(allCategories).limit(null) %}
{% set newsCategoriesInUse = craft.categories.relatedTo(entriesWithNewsCategories) %}


And yes, you probably want to wrap it together with the loop to print the categories in cache tags!