It is perfectly acceptable to embed other DTO instances inside a parent DTO. Of course, this can get prohibitive if the object ends up being extremely large. So this is where you have to make some kind of tradeoff.
One way to get around this is to have a partial representation and a full representation. In cases where you don't need the complete data, you can use the partial representation. In cases where you do need the full data, you can use the full representation. You can even have it so that the full representation embeds the partial representation inside it (composition) and simply defers calls to that (for the partial data).
Another approach I have used before is to tell my mapper (that converts the entity to the DTO) if I need the full data. This way the mapper can decide if the DTO needs to be populated with additional data.