It's a very limited use case. For starters, the functionality present in the local function must be needed at several spots inside the enclosing function such that the resulting local refactoring will be a win in readability. Otherwise I will write the functionality inline, perhaps putting it in a block if that helps.
But at the same time, the functionality must be local or specific enough that I don't have an incentive to refactor the functionality outside of the (not so) enclosing function, where I could perhaps reuse it entirely in another function at some point. It must also be short: otherwise I'm just going to move it out, perhaps putting it in an anonymous namespace (or namespace detail in a header) or some such. It doesn't take much for me to trade locality off in favour of compactness (long functions are a pain to review).
Note that the above is strictly language agnostic. I don't think C++ spins a particular spin on that. If there is one particular C++ advice I have to give on the topic however, it's that I would proscribe using a default by-reference capture ([&]). There'd be no way to tell if that particular lambda expression describe a closure or a local function without carefully reviewing the whole body. Which wouldn't be that bad (it's not that closures are 'scary') if not for the fact that that by-reference captures ([&], [&foo]) allow mutations even if the lambda is not marked mutable, and by-value captures ([=], [foo]) can make an undesirable copy, or even attempt an impossible copy for move-only types. All in all I'd rather not capture anything at all if it's possible (that's what parameters are for!), and use individual captures when needed. It's especially problematic
To sum up:
// foo is expensive to copy, but ubiquitous enough
// that capturing it rather than passing it as a parameter
// is acceptable
auto const& foo_view = foo;
auto do_quux = [&foo_view](arg_type0 arg0, arg_type1 arg1) -> quux_type
{
auto b = baz(foo_view, arg0, arg1);
b.frobnicate;
return foo_view.quux(b);
};
// use do_quux several times later
void foo () { int x; { int y; } /*no more y*/ }