List entries by category
This will exclude empty categories, meaning they don't have any entries associated with them.

{% set entryIds = craft.entries.section('channelHandle').ids() %}
{% set categories = craft.categories.relatedTo({ sourceElement: entryIds }).group('categoryGroupHandle') %}

{% for category in categories %}
    &lt;h2&gt;{{ category.title }}&lt;/h2&gt;
    &lt;ul&gt;
        {% set entries = craft.entries.section('channelHandle').relatedTo(category) %}
        {% for entry in entries %}
            &lt;li&gt;&lt;a href="{{ entry.url }}"&gt;{{ entry.title }}&lt;/a&gt;&lt;/li&gt;
        {% endfor %}
    &lt;/ul&gt;
{% endfor %}