The problem is in your string -> WriterT w m a. It needs to know what the w is. It knows its a monoid but doesn't know anything else about it. The simplest thing is to just tell it what it is.
foldrEntries :: (Entry -> a -> a) -> a -> (String -> a) -> Entries -> a
foldrEntries next done fail' es = runIdentity $ return . fst =<< runWriterT foldIt
where
foldIt = foldrEntriesW (\e -> return . next e) (return done) ((return :: Monad m => a -> WriterT () m a) . fail') es
A second option is to give foldIt a type signature. Unfortunately if you want the a in foldIt to match the a in foldEntries, you have to use scoped type variables extension. Normally the two signatures are not related and the compiler figures both a's are not the same as each other.
{-# LANGUAGE ScopedTypeVariables #-}
...
foldrEntries :: forall a. (Entry -> a -> a) -> a -> (String -> a) -> Entries -> a
foldrEntries next done fail' es = runIdentity $ return . fst =<< runWriterT foldIt
where
foldIt :: Monad m => WriterT () m a
foldIt = foldrEntriesW (\e -> return . next e) (return done) (return . fail') es