Encapsulation means that the the state of an object only happens through a defined interface, and because of this the class can make sure that this state is always valid and in keeping with the purpose of the class.
In some cases therefore, it's perfectly in keeping with the principle of encapsulation to just expose a field publicly - all possible values for the field are valid with all other possible values of all other fields, and therefore the programmer can actively decide to allow the field to be manipulated freely by outside code.
These cases are though mostly restricted to classes that are mostly "plain old data". They also aren't very interesting in this regard, so enough about them.
In other cases, in other languages, one would have a getter and setter method, something like
int getId() to obtain a value and
void setId(int val) to update it.
Properties let us use the same syntax for reading and writing through such methods as we would use to read and write a field. This is a good syntactic sugar, though not vital.
(Actually, due to the way that reflection works and cases such as
DataBinder.Eval it can be handy to have a property even when a field would work fine, but that's another matter).
Up until private setters being introduced (actually, what changed with C# 2 is the syntax for having a private setter and a public or protected getter in the same block), we could have a private method to do the work of the private setter, so private setters aren't really necessary. They're handy though, so while just syntactic sugar, they're pretty useful.
Encapsulation is a matter not of whether your setters (or getters) are public, private, protected or internal, but a matter of whether they are appropriate. Start with a default of every field being private (and for that matter
readonly) and then as necessary add members (whether properties or methods) that alter those fields, and ensure that the object remains valid as they change. This ensures that a class' invariant is kept, which means the rules describing the valid set of states it can be in are never broken (constructors also help by making sure it starts in such a valid state).
As for your last question, to be immutable means that a class has no public, protected or internal setters and no public, protected or internal methods that change any fields. There are degrees of this, in C# there are three degrees possible:
All of a class' instance field's are
readonly, hence even private code can't alter it. It is guaranteed to be immutable (anything that tries to change it won't compile) and possibly optimisations can be done on the back of this.
A class is immutable from the outside because no public member changes anything, but not guaranteed by use of
readonly to not be changed from the inside.
A class is immutable as seen from the outside, though some state is change as an implementation detail. E.g. a field could be memoised, and hence while from the outside an attempt to get it just retrieves the same value, the first such attempt actually calculates it and then stores it for retrieval on subsequent attempts.