def remove_unused_levels_categories(index: T_PDIndex) -> T_PDIndex:
    """
    Remove unused levels from MultiIndex and unused categories from CategoricalIndex
    """
    if isinstance(index, pd.MultiIndex):
        new_index = cast(pd.MultiIndex, index.remove_unused_levels())
        # if it contains CategoricalIndex, we need to remove unused categories
        # manually. See https://github.com/pandas-dev/pandas/issues/30846
        if any(isinstance(lev, pd.CategoricalIndex) for lev in new_index.levels):
            levels = []
            for i, level in enumerate(new_index.levels):
                if isinstance(level, pd.CategoricalIndex):
                    level = level[new_index.codes[i]].remove_unused_categories()
                else:
                    level = level[new_index.codes[i]]
                levels.append(level)
            # TODO: calling from_array() reorders MultiIndex levels. It would
            # be best to avoid this, if possible, e.g., by using
            # MultiIndex.remove_unused_levels() (which does not reorder) on the
            # part of the MultiIndex that is not categorical, or by fixing this
            # upstream in pandas.
            new_index = pd.MultiIndex.from_arrays(levels, names=new_index.names)
        return cast(T_PDIndex, new_index)

    if isinstance(index, pd.CategoricalIndex):
        return index.remove_unused_categories()  # type: ignore[attr-defined]

    return index

    Remove unused levels from MultiIndex and unused categories from CategoricalIndex
    
xarray/core/indexes.py