Lift the duplicated `dir_size` walker and the empty-directory upward-prune
loop out of cache/offline.rs and cache/hot.rs into a shared
cache/fs_utils.rs module. Behaviour-preserving: same boundary semantics,
same skip-on-error policy, same `remove_dir`-only pruning (never
remove_dir_all).
Net delta: -76 LOC across cache/, single source of truth for cache cleanup.