(This example was simplified to be more readable. There are other entitiesThe code is definitely still clunky, and for instancebecause it's a confused attempt, but the AddStatusUpdate has some extradomain behavior -- IRL it actually takes awas: update status category name, and if that category doesn't exist,by adding the category is creatednew status to the archive history. Ultimately I agree with the other answers, this could just be handled by CRUD.)
@AlexeyZimarev gave the correctbest answer, a perfect video on the subject in C# by Jimmy Bogard, but it was apparently moved into a comment below because it didn't give enough information beyond the link. I have a rough draft of my notes summarizing the video in my answer below. Please feel free to comment on the answer with any corrections. The video is an hour long but very worth watching.
Update - 2 Years Later
I think it's a sign of DDD's nascent maturity that even after studying it for 2 years, I still can't promise that I know the "right way" of doing it. Ubiquitous language, aggregate roots, and its approach to behavior-driven design are DDD's valuable contributions to the industry. Persistence ignorance and event sourcing causes confusion, and I think philosophy like that holds it back from wider adoption. But if I had to do this code over again, with what I've learned, I think it would look something like this:
I still welcome any answers to this (very active) post that provide any best-practices code for a valid domain model.