In Reactive forms valueChanges and statusChanges both looks very similar but serves two different purposes.
statusChanges
statusChanges is a property of AbstractControl that emits an event every time when the validation status of the control is recalculated. There are few statuses which is explained in the other answer
valueChanges
valueChanges is a property of AbstractControl that emits an event every time when the value of control changes either using UI or programmatically.
Therefore valueChanges comes useful to do saving when the form is dirty etc.
Hint: Property of AbstractControl means you can attach these events to either FormControl, FormArray or FormGroup
Example:
component.html
<form [formGroup]="form">
<h2 class="text-center">Registration Form</h2>
<br>
<div class="form-group">
<input type="text" class="form-control" placeholder="first Name" formControlName="firstName">
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="last Name" formControlName="lastName">
</div>
<div class="form-group">
<input type="email" class="form-control" placeholder="email" formControlName="email">
<span *ngIf="form.controls['email']?.errors?.required">This field is required</span>
</div>
<br>
<div *ngIf="form.valid">
Valid form
</div>
</form>
component.ts
ngOnInit() {
this.form = this.fb.group({
firstName: ['', Validators.required],
lastName: [''],
email: ['', Validators.required],
});
this.form.valueChanges.subscribe((value) => {
console.log('valueChanges Form value ' + value);
});
this.form.statusChanges.subscribe((status) => {
console.log('statusChanges Status is ' + status);
});
}

A detailed comparison can be found here.