LinkDemand basically requires the calling code to have the specified permission. Demand, on the other hand, requires not only the calling code to have the specified permission, but also the code that called the calling code, and the code that called that, and so on, all the way up the stack (or until an Assert is found; see below).
LinkDemand can be enforced at JIT compile time, because if the JIT compiler hits a statement that calls a method with a LinkDemand, it can determine immediately if the calling code has the permission or not. Demand has to be enforced at runtime every time a call is made to the method, because it is not possible at compile time to know what will be on the stack during any given call. As such, LinkDemand is much more efficient. However, the tradeoff for that efficiency is less security. With LinkDemand, you are trusting that the calling code is not going to let ITS calling code (which may or may not have the permission) use it for nefarious purposes. (In other words, you are trusting that there are no security holes in the calling code that its callers can exploit to gain access indirectly to the method with the LinkDemand.) With Demand, you know that everybody on the stack absolutely has permission (at least up until an Assert is found), so there is no risk from untrusted callers.
Assert is basically a short-circuit for Demand. The security checking that happens with Demand stops if a caller on the stack has an active Assert (in other words, only the callers in the stack up to the Assert have to have the permission). So, like LinkDemand, you have to trust that the code with the Assert cannot be exploited by its callers.
Deny is also a short-circuit for Demand, but instead of asserting a permission it cancels out a permission that a caller might have. You would use this to help prevent possible security holes by ensuring that no extraneous permissions are in effect during a call that might be exploitable.
PermitOnly is like Deny, except instead of denying a specific permission it denies every permission EXCEPT the one specified.
InheritanceDemand, unlike the others, is not directly related to method calls, but says that a class that does not have the permission cannot inherit from the class with the InheritanceDemand. This could be used, for instance, to stop untrusted code from gaining access to protected members of the class that would otherwise be accessible to descendant classes.