To mutate (in the sense used in "nondesctructive mutation for anonymous types") just means to change the state of an object. Here is a simple example:
var sb = new StringBuilder("Hello");
// We mutate the object referenced by sb, so that it contains
// "Hello!" rather than "Hello".
sb.Append("!")
Console.WriteLine(sb.ToString()); // prints Hello!
StringBuilder is a mutable class. Other classes, such as String, are immutable:
var s = "Hello";
// The following expression returns a *new* string "hello",
// but does not mutate the original string itself.
s.ToLower();
Console.WriteLine(s); // still prints Hello
So, what do we do if we want to mutate the contents of an immutable class, for example, to lowercase the contents of a string? We create a new object that contains the modified version. This is what string.ToLower does:
var s1 = "Hello";
var s2 = s1.ToLower();
Console.WriteLine(s1); // prints Hello
Console.WriteLine(s2); // prints hello
This is called non-destructive mutation: The original string s1 still exists, it has not been destroyed. On the other hand, sb.Append("!") in the very first example was destructive: The version of sb containing Hello (without exclamation mark) is no longer accessible.
(Obviously, you can re-use the same variable name when lowercasing a string, e.g. s = s.ToLower(). But that does not change the fact that ToLower creates a new object rather than modifying the old one in-place. s = ... ensures that the variable s points to the new object afterwards.)
So, what does this have to do with anonymous types? Anonymous types in C# are immutable:
var myObject = new { A = 1, B = 2 };
myObject.B = 3; // <- yields a compile-time error
C#9 introduced the with keyword, which allows you to create a new object which is an exact copy of the original object, except for the values you want to change:
var o1 = new { A = 1, B = 2 };
var o2 = o1 with { B = 3 };
// o1: A = 1, B = 2
// o2: A = 1, B = 3