リストが再帰的なんだから仕方ないんじゃない?
リストに対する明示的な再帰が嫌なら
saturate = flip $ foldr (\x t n -> if n < size x then [] else x : t (n - size x)) (const [])
saturate n xs = map snd $ takeWhile ((<= n) . fst) $ zip (scanl1 (+) (map size xs)) xs
あたりが素直なんじゃないかな。