Display entries related to a category (only bottom level)
You can loop through your top level categories and check if descendants are available. Then collect the relevant category IDs that you can later use to filter the ElementCriteriaModel. 

{# Define array before loop #}
{% set bottomLevelCatIds = [] %}

{# Get top level categories only #}
{% set topLevelCats = craft.categories.group('compositions').level(1) %}

{# Loop through categories and collect relevant IDs #}
{% for topLevelCat in topLevelCats %}

    {# Check for child categories #}
    {% if craft.categories.descendantOf(topLevelCat).descendantDist('1')|length %}

        {# Merge child category IDs #}
        {% set 2ndLevelCatIds = craft.categories.descendantOf(topLevelCat).descendantDist('1').ids() %}
        {% set bottomLevelCatIds = bottomLevelCatIds|merge(2ndLevelCatIds) %}

    {% else %}

        {# Merge to level category ID #}
        {% set bottomLevelCatIds = bottomLevelCatIds|merge([topLevelCat.id]) %}

    {% endif %}

{% endfor %}

{# Get the bottom level category models #}
{% set categories = craft.categories.id(bottomLevelCatIds) %}