You can return by reference if you are sure the referenced object will not go out of scope after the function exits, e.g. it's a global object's reference, or member function returning reference to class fields, etc.
This returning reference rule is just same to both lvalue and rvalue reference. The difference is how you want to use the returned reference. As I can see, returning by rvalue reference is rare. If you have function:
Type&& func();
You won't like such code:
Type&& ref_a = func();
because it effectively defines ref_a as Type& since named rvalue reference is an lvalue, and no actual move will be performed here. It's quite like:
const Type& ref_a = func();
except that the actual ref_a is a non-const lvalue reference.
And it's also not very useful even you directly pass func() to another function which takes a Type&& argument because it's still a named reference inside that function.
void anotherFunc(Type&& t) {
// t is a named reference
}
anotherFunc(func());
The relationship of func( ) and anotherFunc( ) is more like an "authorization" that func() agrees anotherFunc( ) might take ownership of (or you can say "steal") the returned object from func( ). But this agreement is very loose. A non-const lvalue reference can still be "stolen" by callers. Actually functions are rarely defined to take rvalue reference arguments. The most common case is that "anotherFunc" is a class name and anotherFunc( ) is actually a move constructor.