How can I output a list of categories that are not empty?
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!