Does interpreter for language L1 have to be written in lower level language L0?
I think the implication of your Tanenbaum quote is that there is no compiler for L1.  In which case yes, the interpreter does have to be written in another language (how else would you run the interpreter?).[1]  It doesn't have to be lower-level; you could write an interpreter for Haskell in ML, say, or vice-versa.  You usually want to use a lower-level language, though, since interpretation is going to impose an order of magnitude speed (and size) overhead you need to win back in the speed of your interpreter for the language to be competitive.

In general, no.  You can write an interpreter for any language L1 in L1, provided you also write a compiler for L1.  Lisps are traditionally bootstrapped by: write an interpreter (a) for Lisp in some other language, then write a compiler (b) for Lisp in Lisp, executed by (a), then write an interpreter (c) for Lisp in Lisp, compiled by (b).  Now you have a Lisp interpreter written in Lisp.

Having said that, a program that takes a program in L1 and produces a program in L0 is a compiler; it compiles to L0.  All compilers compile to some other language[2] which in turn may be compiled some number of additional times, and then is interpreted either by hardware or by another program.

[1] Again, there are techniques for bootstrapping interpreters interpreted by themselves, but they all involve hand-written code in another language (or in the same language but compiled) and are a bit beyond this level.

[2] This is an over-simplification; optimization passes can be written as 'compilers' that compile to their source language and there are other uses for compilers that compile to the same language as the input.  But for your purposes, think of a compiler as compiling to a different language than the source.